home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 3.2 / Ham Radio Version 3.2 (Chestnut CD-ROMs)(1993).ISO / packet / n17jsrc / enet.c < prev    next >
C/C++ Source or Header  |  1991-06-17  |  3KB  |  149 lines

  1. /* Stuff generic to all Ethernet controllers
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. /* Mods by PA0GRI */
  5. #include <stdio.h>
  6. #include "global.h"
  7. #include "mbuf.h"
  8. #include "iface.h"
  9. #include "arp.h"
  10. #include "ip.h"
  11. #include "enet.h"
  12.  
  13. char Ether_bdcst[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  14.  
  15. /* Convert Ethernet header in host form to network mbuf */
  16. struct mbuf *
  17. htonether(ether,data)
  18. struct ether *ether;
  19. struct mbuf *data;
  20. {
  21.     struct mbuf *bp;
  22.     register char *cp;
  23.  
  24.     if((bp = pushdown(data,ETHERLEN)) == NULLBUF)
  25.         return NULLBUF;
  26.  
  27.     cp = bp->data;
  28.  
  29.     memcpy(cp,ether->dest,EADDR_LEN);
  30.     cp += EADDR_LEN;
  31.     memcpy(cp,ether->source,EADDR_LEN);
  32.     cp += EADDR_LEN;
  33.     put16(cp,ether->type);
  34.  
  35.     return bp;
  36. }
  37. /* Extract Ethernet header */
  38. int
  39. ntohether(ether,bpp)
  40. struct ether *ether;
  41. struct mbuf **bpp;
  42. {
  43.     pullup(bpp,ether->dest,EADDR_LEN);
  44.     pullup(bpp,ether->source,EADDR_LEN);
  45.     ether->type = pull16(bpp);
  46.     return ETHERLEN;
  47. }
  48.  
  49. /* Format an Ethernet address into a printable ascii string */
  50. char *
  51. pether(out,addr)
  52. char *out,*addr;
  53. {
  54.     sprintf(out,"%02x:%02x:%02x:%02x:%02x:%02x",
  55.      uchar(addr[0]),uchar(addr[1]),
  56.      uchar(addr[2]),uchar(addr[3]),
  57.      uchar(addr[4]),uchar(addr[5]));
  58.     return out;
  59. }
  60.  
  61. /* Convert an Ethernet address from Hex/ASCII to binary */
  62. int
  63. gether(out,cp)
  64. register char *out;
  65. register char *cp;
  66. {
  67.     register int i;
  68.  
  69.     for(i=6; i!=0; i--){
  70.         *out++ = htoi(cp);
  71.         if((cp = strchr(cp,':')) == NULLCHAR)    /* Find delimiter */
  72.             break;
  73.         cp++;            /* and skip over it */
  74.     }
  75.     return i;
  76. }
  77. /* Send an IP datagram on Ethernet */
  78. int
  79. enet_send(bp,iface,gateway,prec,del,tput,rel)
  80. struct mbuf *bp;    /* Buffer to send */
  81. struct iface *iface;    /* Pointer to interface control block */
  82. int32 gateway;        /* IP address of next hop */
  83. int prec;
  84. int del;
  85. int tput;
  86. int rel;
  87. {
  88.     char *egate;
  89.  
  90.     if(gateway == iface->broadcast) /* This is a broadcast IP datagram */
  91.         return (*iface->output)(iface,Ether_bdcst,iface->hwaddr,IP_TYPE,bp);
  92.  
  93.     egate = res_arp(iface,ARP_ETHER,gateway,bp);
  94.     if(egate != NULLCHAR)
  95.         return (*iface->output)(iface,egate,iface->hwaddr,IP_TYPE,bp);
  96.     return 0;
  97. }
  98. /* Send a packet with Ethernet header */
  99. int
  100. enet_output(iface,dest,source,type,data)
  101. struct iface *iface;    /* Pointer to interface control block */
  102. char *dest;        /* Destination Ethernet address */
  103. char *source;        /* Source Ethernet address */
  104. int16 type;        /* Type field */
  105. struct mbuf *data;    /* Data field */
  106. {
  107.     struct ether ep;
  108.     struct mbuf *bp;
  109.  
  110.     memcpy(ep.dest,dest,EADDR_LEN);
  111.     memcpy(ep.source,source,EADDR_LEN);
  112.     ep.type = type;
  113.     if((bp = htonether(&ep,data)) == NULLBUF){
  114.         free_p(data);
  115.         return -1;
  116.     }
  117.     return (*iface->raw)(iface,bp);
  118. }
  119. /* Process incoming Ethernet packets. Shared by all ethernet drivers. */
  120. void
  121. eproc(iface,bp)
  122. struct iface *iface;
  123. struct mbuf *bp;
  124. {
  125.     struct ether hdr;
  126.  
  127.     /* Remove Ethernet header and kick packet upstairs */
  128.     ntohether(&hdr,&bp);
  129.  
  130.     if(memcmp(hdr.dest,iface->hwaddr,EADDR_LEN) &&
  131.             memcmp(hdr.dest,Ether_bdcst,EADDR_LEN)){
  132.         free_p(bp);
  133.         return;
  134.     }
  135.     switch(hdr.type){
  136.     case REVARP_TYPE:
  137.     case ARP_TYPE:
  138.         arp_input(iface,bp);
  139.         break;
  140.     case IP_TYPE:
  141.         ip_route(iface,bp,hdr.dest[0] & 1);
  142.         break;
  143.     default:
  144.         free_p(bp);
  145.         break;
  146.     }
  147. }
  148.  
  149.